import Head from "../components/head";
import { useState, useEffect } from "react";
import "../assets/css/upload.scss";
import { Input, Cell, Progress, Button, Overlay, Toast } from "react-vant";
import { Plus, VideoO, Cross } from "@react-vant/icons";
import api from "../util/api";
import { curFile } from "../util/curFiles";
import { useNavigate } from "react-router-dom";

export default function Upload() {
  //遮罩层显示与隐藏
  const [visible, setVisible] = useState(false);

  //图片预览
  const [isShowimg, setisShowimg] = useState(false);

  // 上传进度
  const [curProgress, setCurProgress] = useState(0);

  //存储上传文件名称并存为数组
  const [fileName, setFileName] = useState(Array);

  // 存储选中上传文件名称
  const [filename, setfilename] = useState("");
  // 上传按钮禁用状态
  const [btnState, setBtnState] = useState(true);

  // 上传按钮显示
  const [btnShow, setBtnShow] = useState(true);

  // 暂停还是继续
  const [stastop, setStaStop] = useState(false);

  // 路由方法
  const navigate = useNavigate();

  //存储上传章节信息
  const [chaptArray, setChaptArray] = useState(Array);

  // 是否继续添加章节
  const [isAdd, setIsAdd] = useState(false);
  // 存储添加课程
  const [courseObj, setcourseObj] = useState({
    title: "", //课程标题
    courseDesc: "", //课程描述
    language: "", //语言
    slill: "", // 技术水平
    price: "", //价格
    img: "", // 课程封面
    publisher: JSON.parse(localStorage.getItem("user")).note._id, // 发布者
  });

  // 存储到添加章节
  const [chapterObj, setChapterObj] = useState({
    name: "",
    videoUrl: "",
  });

  // 监听chapterObj的变化
  useEffect(() => {
    if (chapterObj.name && chapterObj.videoUrl) {
      setChaptArray([...chaptArray, chapterObj]);
      setIsAdd(true);
    }
  }, [chapterObj]);

  // 修改是否添加的状态
  const handelContinue = () => {
    setIsAdd(false);
    setChapterObj({
      name: "",
      videoUrl: "",
    });
  };

  // 绑定课程标题
  const handeltitle = (e: any) => {
    setcourseObj({
      ...courseObj,
      title: e.target.value,
    });
  };

  // 绑定课程描述
  const handeldesc = (e: any) => {
    setcourseObj({
      ...courseObj,
      courseDesc: e.target.value,
    });
  };

  // 绑定语言
  const handelLanguage = (e: any) => {
    setcourseObj({
      ...courseObj,
      language: e.target.value,
    });
  };

  // 绑定技术水平
  const handelSkill = (e: any) => {
    setcourseObj({
      ...courseObj,
      slill: e.target.value,
    });
  };

  // 绑定课程价格
  const handelPrice = (e: any) => {
    setcourseObj({
      ...courseObj,
      price: e,
    });
  };

  // 绑定章节名称
  const handelName = (e: any) => {
    setChapterObj({
      ...chapterObj,
      name: e,
    });
  };

  // 图片上传事件委托
  const handelimg = () => {
    document.getElementById("file-input")?.click();
  };

  // 获取当前上传图片
  const handelchangeimg = (e: any) => {
    let selectFiles = e.target.files;
    handelSelectedFiles(selectFiles);
  };

  // 图片上传逻辑
  const handelSelectedFiles = async (files: any) => {
    for (let i = 0; i < files.length; i++) {
      let file = files[i];

      if (file.type.startsWith("image/")) {
        let reader = new FileReader();
        reader.onload = async function () {
          let formData = new FormData();
          formData.append("imageFile", file);
          try {
            const response = await api.post("/upload/img", formData);
            setcourseObj({ ...courseObj, img: response.data });
            setisShowimg(true);
          } catch (error) {
            console.error("图片上传失败:", error);
          }
        };
        reader.readAsDataURL(file);
      }
    }
  };

  // 视频上传事件委托
  const handelvideo = () => {
    document.getElementById("file-input-video")?.click();
  };

  // 选择文件并存储文件名
  const handelchangevideo = async (e: any) => {
    const file = e.target.files[0];
    setFileName([...fileName, file.name]);
    setfilename(file.name);
    setBtnState(false);
  };

  // 大文件上传逻辑
  const handelupload = async () => {
    setBtnShow(false);
    const fileInput = document.getElementById("file-input-video");
    const file = fileInput.files[0];
    const chunks = await curFile(file); // curFile是一个将文件切分成块的函数
    try {
      const response = await api.post("/upload/check-file", {
        fileHash: chunks[0].hash,
      });
      if (response.code === 200) {
        Toast.success("秒传成功");
        setChapterObj({
          ...chapterObj,
          videoUrl: response.path,
        });
        setVisible(false);
        setBtnShow(true);
        return;
      }
    } catch (error) {
      localStorage.setItem(file.name, "0");
      console.error("检查文件失败");
    }
    let breakpoint = localStorage.getItem(file.name) || 0;
    // 循环上传切片
    for (let i = breakpoint; i < chunks.length; i++) {
      localStorage.setItem(file.name, i);
      if (i === chunks.length - 1) {
        setBtnShow(true);
        setBtnState(true);
      }
      const formData = new FormData();
      formData.append("file", chunks[i].chunkData);
      formData.append("filename", file.name);
      formData.append("totalChunks", chunks.length);
      formData.append("currentChunk", chunks[i].index);

      try {
        const res = await api.post("/upload/video", formData, {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        });
        setCurProgress(res.progress);
      } catch (error) {
        console.error(error);
        return;
      }
    }
    // 发送合并请求
    try {
      const postData = {
        filename: file.name,
        totalChunks: chunks.length,
        fileHash: chunks[0].hash,
      };
      const res = await api.post("/upload/merge", postData, {
        headers: {
          "Content-Type": "application/json",
        },
      });
      setChapterObj({
        ...chapterObj,
        videoUrl: res.path,
      });
      Toast.success("上传成功");
      setVisible(false);
    } catch (error) {
      console.error(error);
    }
  };

  // 提交课程
  const handelclike = () => {
    api.post("/upload/course", {
      courseObj: courseObj,
      chaptArray: chaptArray,
    });
    Toast.success("发布成功");
    navigate("/course");
  };
  return (
    <div className="upload">
      <Head />
      <div className="upload-main">
        <div className="upload-title">
          <p>上传新课程</p>
        </div>
        <div className="upload-input">
          <p>标题</p>
          <div className="input1">
            <input
              type="text"
              placeholder="这里输入课程标题"
              value={courseObj.title}
              onChange={handeltitle}
            />
          </div>
          <br />
          <p>描述</p>
          <div className="textarea1">
            <textarea
              placeholder="这里输入课程描述"
              value={courseObj.courseDesc}
              onChange={handeldesc}
            ></textarea>
          </div>
        </div>
        {isShowimg ? (
          <div className="upload-img-succes">
            <div className="succes-img">
              <img src={courseObj.img} alt="" />
            </div>
            <div className="succes-p" onClick={handelimg}>
              <p>点击上传新封面图</p>
            </div>
          </div>
        ) : (
          <div className="upload-img" onClick={handelimg}>
            <p>上传封面图片</p>
            <p>将文件拖放到此处或者预览</p>
          </div>
        )}

        <input
          type="file"
          id="file-input"
          style={{ display: "none" }}
          onChange={(e) => handelchangeimg(e)}
        />
        <input
          type="file"
          id="file-input-video"
          style={{ display: "none" }}
          onChange={(e) => handelchangevideo(e)}
        />
        <div className="upload-select">
          <div className="chinese">
            <p>语言</p>
            <select
              name=""
              id=""
              value={courseObj.language}
              onChange={handelLanguage}
            >
              <option value="" disabled hidden>
                请选择
              </option>
              <option value="设计IT">设计IT</option>
              <option value="自媒体">自媒体</option>
              <option value="精品课">精品课</option>
            </select>
          </div>
          <div className="skill">
            <p>技能水平</p>
            <select
              name=""
              id=""
              value={courseObj.slill}
              onChange={handelSkill}
            >
              <option value="" disabled hidden>
                请选择
              </option>
              <option value="空间设计">空间设计</option>
              <option value="绘画素描">绘画素描</option>
              <option value="项目开发">项目开发</option>
            </select>
          </div>
        </div>
        <div className="upload-title">
          <p>课程内容</p>
        </div>
        <div className="upload-course">
          {chaptArray &&
            chaptArray.map((item, index) => (
              <div className="upload-course-item" key={index}>
                <p>第{index + 1}章</p>
                <Cell>
                  <Input
                    prefix="标题"
                    placeholder="请输入标题"
                    value={item.name}
                    onChange={handelName}
                  />
                </Cell>
                <br />
                <Button
                  icon={<VideoO />}
                  onClick={() => {
                    setVisible(true);
                    setfilename(fileName[index]);
                  }}
                >
                  上传课程视频
                </Button>
                {fileName && <span>{fileName[index]}</span>}
              </div>
            ))}
          {isAdd ? (
            <></>
          ) : (
            <div className="upload-course-item">
              <p>第{chaptArray.length + 1}章</p>
              <Cell>
                <Input
                  prefix="标题"
                  placeholder="请输入标题"
                  value={chapterObj.name}
                  onChange={handelName}
                />
              </Cell>
              <br />
              <Button
                icon={<VideoO />}
                onClick={() => {
                  if (chapterObj.name) {
                    setVisible(true);
                  } else {
                    Toast.fail("请先输入标题");
                  }
                }}
              >
                上传课程视频
              </Button>
              {fileName && <span>{fileName[chaptArray.length + 1]}</span>}
            </div>
          )}

          <div className="upload-course-add">
            <Button
              className="button1"
              icon={<Plus />}
              onClick={handelContinue}
            >
              继续添加章节
            </Button>
            <Overlay
              visible={visible}
              onClick={() => {
                setVisible(false);
              }}
              style={{
                height: "100%",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
              }}
            >
              <div
                style={{
                  width: "90vw",
                  height: "50vh",
                  backgroundColor: "#fff",
                  borderRadius: 4,
                }}
                className="upload-dialog"
              >
                <div className="uoload-dialog-title">
                  <p>上传到当前章节</p>
                  <div>
                    <Cross
                      onClick={() => {
                        setVisible(false);
                      }}
                    />
                  </div>
                </div>
                <br />
                <br />
                <div className="upload-dialog-main" onClick={handelvideo}>
                  {filename ? (
                    <span>{filename}</span>
                  ) : (
                    <span>点击此处选择你要上传的视频文件</span>
                  )}
                </div>
                <div className="upload-dialog-toast">
                  {curProgress === 0 || curProgress === 100 ? (
                    <span>暂无上传</span>
                  ) : (
                    <>
                      <Progress percentage={curProgress.toFixed(2)} />
                    </>
                  )}
                  <div className="upload-button">
                    {btnShow ? (
                      <button onClick={handelupload} disabled={btnState}>
                        上传
                      </button>
                    ) : (
                      <button>
                        {stastop ? (
                          <span>继续上传</span>
                        ) : (
                          <span>暂停上传</span>
                        )}
                      </button>
                    )}
                  </div>
                </div>
              </div>
            </Overlay>
          </div>
        </div>
        <div className="upload-title">
          <p>其他信息</p>
        </div>
        <div className="upload-foot">
          <Cell>
            <Input
              prefix="￥"
              placeholder="请输入课程价格"
              value={courseObj.price}
              onChange={handelPrice} 
            />
          </Cell>
          <button onClick={handelclike}>提交课程</button>
        </div>
      </div>
    </div>
  );
}
